#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include "common.h"
#include "wifi.h"
#include <sys/select.h>


#define BUFFER_SIZE 1024
#define CONF_FILE "/reemoon/config/wpa_supplicant.conf"
#define INTERFACE "wlan0"

extern bool SYSTEM_RUNNING_FALG;

static wifi_info_t wifi_info;
static int fifo_rx_fd = -1;
static int fifo_tx_fd = -1;

static void *rev_pth(void *arg);
static void data_process(char *data, int len);

static int send_data_to_fifo(char *data, int len)
{
    if (fifo_tx_fd)
    {
        return write (fifo_tx_fd, data, len);
    }
    else
    {
        reemoon_warn ("wifi app fifo init failed\n");
        return -1;
    }
}

int wifi_connect(void) 
{
    return send_data_to_fifo(WIFI_CTRL_CONNECT, strlen(WIFI_CTRL_CONNECT));
}

int wifi_disconnect(void) 
{
    return send_data_to_fifo(WIFI_CTRL_DISCONNECT, strlen(WIFI_CTRL_DISCONNECT));
}

void wifi_status(void) 
{
    send_data_to_fifo(WIFI_CTRL_STATUS, strlen(WIFI_CTRL_STATUS));
}

static pthread_t rev_pth_id;
static pthread_t status_pth_id;
#define FIFO_TX_PATH "/reemoon/config/wifi_tx_fifo"
#define FIFO_RX_PATH "/reemoon/config/wifi_rx_fifo"

static bool wifi_connect_status = false;

void *wifi_status_pth_id(void *arg)
{
    while(SYSTEM_RUNNING_FALG)
    {
        if (wifi_connect_status == true)
            wifi_status();
        sleep(1);
    }
}

int wifi_app_init(void)
{
    pthread_create(&rev_pth_id, NULL, rev_pth, NULL);
    pthread_create(&status_pth_id, NULL, wifi_status_pth_id, NULL);
}

static void *rev_pth(void *arg)
{
    fd_set read_fds;
    struct timeval timeout;
    int bytes_read;
    char buffer[1024];

    // 检查管道文件是否存在
    if (access(FIFO_RX_PATH, F_OK) == 0) {
        reemoon_ignore ("命名管道 %s 已存在。\n", FIFO_RX_PATH);
    }
	// 创建管道
	else if (mkfifo(FIFO_RX_PATH, 0777) == -1) {
        perror("mkfifo");
        return NULL;
    }
    // 检查管道文件是否存在
    if (access(FIFO_TX_PATH, F_OK) == 0) {
        reemoon_ignore ("命名管道 %s 已存在。\n", FIFO_TX_PATH);
    }
	// 创建管道
	else if (mkfifo(FIFO_TX_PATH, 0777) == -1) {
        reemoon_error ("mkfifo");
        return NULL;
    }

    fifo_rx_fd = open(FIFO_RX_PATH, O_RDONLY  | O_NONBLOCK);
    if (fifo_rx_fd == -1) {
        reemoon_error("open fifo_rx_fd");
        return NULL;
    }
    reemoon_ignore ("fifo_rx_fd : %d\n", fifo_rx_fd);

    fifo_tx_fd = open(FIFO_TX_PATH, O_WRONLY);
    if (fifo_tx_fd == -1) {
        reemoon_error ("open fifo_tx_fd");
        return NULL;
    }
    reemoon_ignore("fifo_tx_fd : %d\n", fifo_tx_fd);
    wifi_status();
    reemoon_info ("wifi master app ready...\n");
    while (SYSTEM_RUNNING_FALG) 
    {
        // 清空文件描述符集合
        FD_ZERO(&read_fds);
        // 将管道文件描述符加入集合
        FD_SET(fifo_rx_fd, &read_fds);

        // 设置超时时间为5秒
        timeout.tv_sec = 5;
        timeout.tv_usec = 0;

        // 使用select监听管道
        int result = select(fifo_rx_fd + 1, &read_fds, NULL, NULL, &timeout);
        if (result > 0) {  // 有数据可读
            if (FD_ISSET(fifo_rx_fd, &read_fds)) {
                bytes_read = read(fifo_rx_fd, buffer, sizeof(buffer) - 1);
                if (bytes_read > 0) {
                    buffer[bytes_read] = '\0';  // 确保字符串结尾
                    reemoon_ignore ("接收到数据: %s\n", buffer);
                    data_process(buffer, bytes_read);
                } else if (bytes_read == 0) {
                    reemoon_info ("wifi_app 端关闭了管道。\n");
                    break;  // 如果对端关闭了管道，退出循环
                } else {
                    reemoon_error ("read");
                }
            }
        } else if (result == 0) {  // 超时
            reemoon_ignore ("超时，未接收到数据。\n");
            continue;
        } else {  // 错误
            reemoon_error ("select");
            break;  // 如果发生错误，退出循环
        }
    }
    // 关闭管道
    close(fifo_rx_fd);
    
    wifi_app_init();// 重新启动
    system("/reemoon/wifi_app &");
    reemoon_info ("wifi fifo restart\n");
    return NULL;
}

static void data_process(char *data, int len)
{
    if (len == sizeof(wifi_info_t))
    {
        memcpy(&wifi_info, data, sizeof(wifi_info));
        // reemoon_info ("ssid:%s\n", wifi_info.ssid);
        // reemoon_info ("signal:%d dBm\n", wifi_info.signal);
        // reemoon_info ("freq:%d MHz\n", wifi_info.freq);
        wifi_connect_status = true;
    }
    else if (strcmp (data, WIFI_CTRL_CONNECT) == 0)
    {
        wifi_connect_status = true;
    }
    else if (strcmp (data, WIFI_CTRL_DISCONNECT) == 0)
    {
        wifi_connect_status = false;
    }
}

void wifi_fifo_deinit(void)
{
    if (rev_pth_id > 0)
        pthread_cancel(rev_pth_id);
    if (status_pth_id > 0)
        pthread_cancel (status_pth_id);
    reemoon_info ("wifi fifo deinit\n");
}